from flask import Flask, request, jsonify, render_template
from flask_cors import CORS
import numpy as np
from py.PE_cal import PE_calculator
import py.PE_cal as PE_cal
from py.butler import parameters, butler, calculate_butler_3, calculate_binary_viscosity, calculate_ternary_viscosity
import traceback
import logging



# 配置日志
logging.basicConfig(level=logging.INFO,
                format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

app = Flask(__name__)
CORS(app)

def parse_ternary_system(system):
    """解析三元系统名称，返回三个二元系统名称"""
    try:
        # 分割系统名称，例如 "Mg_Al_La" -> ["Mg", "Al", "La"]
        elements = system.split('_')
        if len(elements) != 3:
            raise ValueError(f"三元系统名称格式错误: {system}")
                # 生成三个二元系统名称

        resault = [
            f"{elements[0]}_{elements[1]}",  # Mg_Al
            f"{elements[1]}_{elements[2]}",  # Al_La
            f"{elements[0]}_{elements[2]}"   # Mg_La
        ]
        logger.info(f"解析得到的三元系统: {resault}")
        # 返回三个二元系统名称
        return resault

    except Exception as e:
        logger.error(f"解析三元系统名称时出错: {str(e)}")
        raise

@app.route('/')
def index():
    return render_template('surfacetension.html')

@app.route('/calculate_surface_tension', methods=['GET', 'POST'])
def calculate_surface_tension():
    try:
        if request.method == 'POST':
            # 获取JSON数据
            data = request.get_json()
            if not data:
                return jsonify({
                    'success': False,
                    'message': '请求中没有JSON数据'
                }), 400
                
            logger.info(f"收到计算请求: {data}")
            
            # 验证必需字段
            required_fields = ['temperature', 'system_type', 'system', 'composition']
            missing_fields = [field for field in required_fields if field not in data]
            if missing_fields:
                return jsonify({
                    'success': False,
                    'message': f'缺少必需字段: {", ".join(missing_fields)}'
                }), 400
                
            # 提取并验证参数
            try:
                T = float(data['temperature'])
                if T <= 0:
                    raise ValueError(f"温度必须大于0K，当前值为 {T}K")
                    
                system_type = data['system_type']
                if system_type not in ['binary', 'ternary']:
                    raise ValueError(f"不支持的系统类型: {system_type}，必须是 'binary' 或 'ternary'")
                    
                system = data['system']
                composition = data['composition']
                
                # 验证成分
                if not isinstance(composition, list):
                    raise ValueError("成分必须是列表")
                    
                if system_type == 'binary' and len(composition) != 2:
                    raise ValueError("二元系统必须提供2个成分")
                elif system_type == 'ternary' and len(composition) != 3:
                    raise ValueError("三元系统必须提供3个成分")
                    
                # 验证成分值
                composition = [float(x) for x in composition]
                if any(x < 0 or x > 1 for x in composition):
                    raise ValueError("所有成分值必须在0到1之间")
                    
                if abs(sum(composition) - 1) > 1e-6:
                    raise ValueError("成分之和必须等于1")
                    
            except (TypeError, ValueError) as e:
                return jsonify({
                    'success': False,
                    'message': f'参数验证失败: {str(e)}'
                }), 400
                
            # 根据系统类型进行计算
            if system_type == 'binary':
                # 二元系统计算（原有代码）
                L12, theta, M, rou = parameters(system, T)
                beta = 0.75
                x1 = composition[0]
                result = butler(T, beta, L12, theta, M, rou, x1)
            elif system_type == 'ternary':
                # 三元系统计算
                try:
                    # 解析三元系统名称
                    binary_systems = parse_ternary_system(system)
                    logger.info(f"解析得到的三元系统: {binary_systems}")
                    
                    # 计算三个二元系统的参数
                    params = []
                    for binary_system in binary_systems:
                        L12, theta, M, rou = parameters(binary_system, T)
                        params.append((L12, theta, M, rou))
                        
                    # 提取三元计算所需的参数
                    l_12 = params[0][0]  # Mg_Al的L12
                    l_23 = params[1][0]  # Al_La的L12
                    l_13 = params[2][0]  # Mg_La的L12
                    
                    # 合并theta, M, rou参数
                    theta = [p[1][0] for p in params]  # 三个二元系统的theta
                    M = [p[2][0] for p in params]      # 三个二元系统的M
                    rou = [p[3][0] for p in params]    # 三个二元系统的rou
                    
                    # 计算三元系统表面张力
                    beta = 0.75
                    x1, x2, x3 = composition
                    result = calculate_butler_3(T, beta, l_12, l_23, l_13, theta, M, rou, x1, x2, x3)
                    
                except Exception as e:
                    logger.error(f"三元系统计算出错: {str(e)}")
                    return jsonify({
                        'success': False,
                        'message': f"三元系统计算出错: {str(e)}"
                    }), 500
                    
            return jsonify({
                'success': True,
                'result': float(result),
                'message': '计算成功'
            })
            
    except Exception as e:
        logger.error(f"服务器错误: {str(e)}")
        logger.error(f"错误追踪: {traceback.format_exc()}")
        return jsonify({
            'success': False,
            'message': f'服务器错误: {str(e)}'
        }), 500

# 黏度计算接口
@app.route('/calculate_viscosity', methods=['GET', 'POST'])
def calculate_viscosity():
    try:
        if request.method == 'POST':
            # 获取JSON数据
            data = request.get_json()
            if not data:
                return jsonify({
                    'success': False,
                    'message': '请求中没有JSON数据'
                }), 400
                
            logger.info(f"收到黏度计算请求: {data}")
            
            # 验证必需字段
            required_fields = ['temperature', 'system_type', 'system', 'composition']
            missing_fields = [field for field in required_fields if field not in data]
            if missing_fields:
                return jsonify({
                    'success': False,
                    'message': f'缺少必需字段: {", ".join(missing_fields)}'
                }), 400
                
            # 提取并验证参数
            try:
                T = float(data['temperature'])
                if T <= 0:
                    raise ValueError(f"温度必须大于0K，当前值为 {T}K")
                    
                system_type = data['system_type']
                if system_type not in ['binary', 'ternary']:
                    raise ValueError(f"不支持的系统类型: {system_type}，必须是 'binary' 或 'ternary'")
                    
                system = data['system']
                composition = data['composition']
                
                # 验证成分
                if not isinstance(composition, list):
                    raise ValueError("成分必须是列表")
                    
                if system_type == 'binary' and len(composition) != 2:
                    raise ValueError("二元系统必须提供2个成分")
                elif system_type == 'ternary' and len(composition) != 3:
                    raise ValueError("三元系统必须提供3个成分")
                    
                # 验证成分值
                composition = [float(x) for x in composition]
                if any(x < 0 or x > 1 for x in composition):
                    raise ValueError("所有成分值必须在0到1之间")
                    
                if abs(sum(composition) - 1) > 1e-6:
                    raise ValueError("成分之和必须等于1")
                    
            except (TypeError, ValueError) as e:
                return jsonify({
                    'success': False,
                    'message': f'参数验证失败: {str(e)}'
                }), 400
                
            # 根据系统类型进行计算
            try:
                if system_type == 'binary':
                    # 二元系统黏度计算
                    x1 = composition[0]
                    x2 = composition[1]
                    result = calculate_binary_viscosity(system, T, x1, x2)
                elif system_type == 'ternary':
                    # 三元系统黏度计算
                    x1, x2, x3 = composition
                    result = calculate_ternary_viscosity(system, T, x1, x2, x3)
                    
                return jsonify({
                    'success': True,
                    'result': float(result),
                    'message': '黏度计算成功'
                })
                
            except Exception as e:
                logger.error(f"黏度计算出错: {str(e)}")
                logger.error(f"错误追踪: {traceback.format_exc()}")
                return jsonify({
                    'success': False,
                    'message': f"黏度计算出错: {str(e)}"
                }), 500
            
    except Exception as e:
        logger.error(f"服务器错误: {str(e)}")
        logger.error(f"错误追踪: {traceback.format_exc()}")
        return jsonify({
            'success': False,
            'message': f'服务器错误: {str(e)}'
        }), 500



if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000) 